require "nvchad.mappings"

-- add yours here

local map = vim.keymap.set

map("n", ";", ":", { desc = "CMD enter command mode" })
map("i", "jk", "<ESC>")

-- map({ "n", "i", "v" }, "<C-s>", "<cmd> w <cr>")

-- Oil
map("n", "-", "<CMD>Oil --float<CR>", { desc = "Open parent directory" })

map("n", ";", ":", { desc = "CMD enter command mode" })

-- Jump between markdown headers
map("n", "gj", [[/^##\+ .*<CR>]], { buffer = true, silent = true })
map("n", "gk", [[?^##\+ .*<CR>]], { buffer = true, silent = true })

-- Exit insert mode without hitting Esc
map("i", "jj", "<Esc>", { desc = "Esc" })

-- Make Y behave like C or D
map("n", "Y", "y$")
-- Select all
map("n", "==", "gg<S-v>G")

-- Keep window centered when going up/down
map("n", "J", "mzJ`z")
map("n", "<C-d>", "<C-d>zz")
map("n", "<C-u>", "<C-u>zz")
map("n", "n", "nzzzv")
map("n", "N", "Nzzzv")

-- Paste without overwriting register
map("v", "p", '"_dP')

-- Copy text to " register
map("n", "<leader>y", '"+y', { desc = 'Yank into " register' })
map("v", "<leader>y", '"+y', { desc = 'Yank into " register' })
map("n", "<leader>Y", '"+Y', { desc = 'Yank into " register' })

-- Delete text to " register
map("n", "<leader>d", '"_d', { desc = 'Delete into " register' })
map("v", "<leader>d", '"_d', { desc = 'Delete into " register' })

-- Get out Q
map("n", "Q", "<nop>")

-- close buffer
map("n", "<leader>q", "<cmd>bd<CR>", { desc = "Close Buffer" })

-- Close buffer without closing split
map("n", "<leader>w", "<cmd>bp|bd #<CR>", { desc = "Close Buffer; Retain Split" })

-- Replace word under cursor across entire buffer
map("n", "<leader>s", [[:%s/\<<C-r><C-w>\>/<C-r><C-w>/gI<Left><Left><Left>]], { desc = "Replace word under cursor" })

-- Jump to plugin management file
map("n", "<leader>vpp", "<cmd>e ~/.config/nvim/lua/plugins/init.lua<CR>", { desc = "Jump to configuration file" })

-- Run Tests
map("n", "<leader>t", "<cmd>lua require('neotest').run.run()<CR>", { desc = "Run Test" })
map("n", "<leader>tf", "<cmd>lua require('neotest').run.run(vim.fn.expand('%'))<CR>", { desc = "Run Test File" })
map(
  "n",
  "<leader>td",
  "<cmd>lua require('neotest').run.run(vim.fn.getcwd())<CR>",
  { desc = "Run Current Test Directory" }
)
map("n", "<leader>tp", "<cmd>lua require('neotest').output_panel.toggle()<CR>", { desc = "Toggle Test Output Panel" })
map("n", "<leader>tl", "<cmd>lua require('neotest').run.run_last()<CR>", { desc = "Run Last Test" })
map("n", "<leader>ts", "<cmd>lua require('neotest').summary.toggle()<CR>", { desc = "Toggle Test Summary" })

-- Debug Tests
map("n", "<leader>dg", "<cmd>GoDebug<CR>", { desc = "Start golang Debugging" })
map("n", "<leader>dc", "<cmd>:lua require('dap').continue()<CR>", { desc = "Start Debugging" })
map("n", "<leader>dso", "<cmd>DapStepOver<CR>", { desc = "Step Over" })
map("n", "<leader>dsi", "<cmd>DapStepInto<CR>", { desc = "Step Into" })
map("n", "<leader>dsu", "<cmd>DapStepOut<CR>", { desc = "Step Out" })
map("n", "<leader>dst", "<cmd>DapStepTerminate<CR>", { desc = "Stop Debugger" })
map("n", "<leader>b", "<cmd>lua require'dap'.toggle_breakpoint()<CR>", { desc = "Toggle Breakpoint" })
map(
  "n",
  "<leader>B",
  "<cmd>lua require'dap'.set_breakpoint(vim.fn.input('Breakpoint condition: '))<CR>",
  { desc = "Toggle Breakpoint Condition" }
)
map("n", "<leader>E", "<cmd>lua require'dap'.set_exception_breakpoints()<CR>", { desc = "Toggle Exception Breakpoint" })
map(
  "n",
  "<leader>dr",
  "<cmd>lua require'dapui'.float_element('repl', { width = 100, height = 40, enter = true })<CR>",
  { desc = "Show DAP REPL" }
)
map(
  "n",
  "<leader>ds",
  "<cmd>lua require'dapui'.float_element('scopes', { width = 150, height = 50, enter = true })<CR>",
  { desc = "Show DAP Scopes" }
)
map(
  "n",
  "<leader>df",
  "<cmd>lua require'dapui'.float_element('stacks', { width = 150, height = 50, enter = true })<CR>",
  { desc = "Show DAP Stacks" }
)
map(
  "n",
  "<leader>db",
  "<cmd>lua require'dapui'.float_element('breakpoints', { enter = true })<CR>",
  { desc = "Show DAP breakpoints" }
)
map("n", "<leader>do", "<cmd>lua require'dapui'.toggle()<CR>", { desc = "Toggle DAP UI" })
map("n", "<leader>dl", "<cmd>lua require'dap'.run_last()<CR>", { desc = "Debug Last Test" })

-- Copy file paths
map("n", "<leader>cf", '<cmd>let @+ = expand("%")<CR>', { desc = "Copy File Name" })
map("n", "<leader>cp", '<cmd>let @+ = expand("%:p")<CR>', { desc = "Copy File Path" })
-- Dismiss Noice Message
map("n", "<leader>nd", "<cmd>NoiceDismiss<CR>", { desc = "Dismiss Noice Message" })

-- Resize with arrows
map("n", "<C-S-Down>", ":resize +2<CR>", { desc = "Resize Horizontal Split Down" })
map("n", "<C-S-Up>", ":resize -2<CR>", { desc = "Resize Horizontal Split Up" })
map("n", "<C-Left>", ":vertical resize -2<CR>", { desc = "Resize Vertical Split Down" })
map("n", "<C-Right>", ":vertical resize +2<CR>", { desc = "Resize Vertical Split Up" })

-- Stay in indent mode
map("v", "<", "<gv")
map("v", ">", ">gv")

map({ "n", "o", "x" }, "<s-h>", "^", { desc = "Jump to beginning of line" })
map({ "n", "o", "x" }, "<s-l>", "g_", { desc = "Jump to end of line" })

-- Move block
map("v", "J", ":m '>+1<CR>gv=gv", { desc = "Move Block Down" })
map("v", "K", ":m '<-2<CR>gv=gv", { desc = "Move Block Up" })

-- Search for highlighted text in buffer
map("v", "//", 'y/<C-R>"<CR>', { desc = "Search for highlighted text" })

-- -- Autocommands
-- vim.api.nvim_create_augroup("custom_buffer", { clear = true })
--
-- -- start terminal in insert mode
-- vim.api.nvim_create_autocmd("TermOpen", {
--   desc = "Auto enter insert mode when opening a terminal",
--   group = "custom_buffer",
--   pattern = "*",
--   callback = function()
--     -- Wait briefly just in case we immediately switch out of the buffer (e.g. Neotest)
--     vim.defer_fn(function()
--       if vim.api.nvim_buf_get_option(0, "buftype") == "terminal" then
--         vim.cmd [[startinsert]]
--       end
--     end, 100)
--   end,
-- })
--
-- -- highlight yanks
-- vim.api.nvim_create_autocmd("TextYankPost", {
--   group = "custom_buffer",
--   pattern = "*",
--   callback = function()
--     vim.highlight.on_yank { timeout = 200 }
--   end,
-- })
--
vim.api.nvim_del_keymap("n", "<C-s>")
vim.api.nvim_del_keymap("n", "<C-c>")
